<?php

/*
 * core/init.php
 *
 * Set of functions to initialize the core
 */

// global to allow if we are really executing the normal initialization process
$_initProcess = false;

/*
 * startInitProcess()
 * start the standard initialization process
 */
function startInitProcess()
{
	global $_initProcess;
	$_initProcess = true;
}

/*
 * displayChoices()
 * propose a choise to user of what to initialize
 */
function displayChoices()
{
	$html = '';
	$html .= '<form method="post" action="'.Util::getUrlScriptName().'">' . "\n";
	$html .= '<input type="hidden" name="defined" value="yes" /> <br>' . "\n";
	$html .= '<input type="checkbox" name="createdb" /> Drop & create database ?  <br>' . "\n";
	$html .= '<input type="checkbox" name="initdb" /> Init database ?  <br>' . "\n";
	$html .= '<input type="checkbox" name="initusergroup" /> Init default users and groups ?  <br>' . "\n";
	$html .= '<input type="checkbox" name="initperms" value="yes" checked /> Init / update services/methods permissions ?  <br>' . "\n";
	$html .= '<input type="checkbox" name="initsite" /> Init site specific (script site_initialize.php) ?  <br>' . "\n";
	$html .= '<input type="submit" /> <input type="reset" /> <br>' . "\n";
	$html .= '</form>' . "\n";

	print( $html );
}

/*
 * createDatabase()
 * drop if exist and create the database
 */
function createDatabase()
{
	$dbName = Conf::$c['db']['name'];

	$sqlDestroy  = 'DROP DATABASE '.$dbName;
	$sqlCreate = 'CREATE DATABASE '.$dbName;

	if( !db()->execute( $sqlDestroy ) )
	{
		print( 'createDatabase: unable to drop database, certainly does not exist <br>'."\n" );
	}

	if( !db()->execute( $sqlCreate ) )
	{
		die( 'createDatabase: unable to create database '.$dbName."\n" );
	}

	if( !db()->useDatabase( $dbName ) )
	{
		die( 'createDatabase: unable to use database .'.$dbName."\n" );
	}

	print( 'createDatabase: database "'.$dbName.'" created. <br>'."\n" );
}

/*
 * execute given SQL file
 */
// TODO: handle UTF8 encoding
function executeSQLFile( $filename )
{
	if( !file_exists($filename) )
	{
		print( 'executeSQLFile: file ('.$filename.') does not exist.<br>' );
		return false;
	}

	$lines = file( $filename, FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES );

	$sql = '';

	foreach( $lines as $lno => $line )
	{
		print( '<code>'.$line.'</code><br>'."\n" );

		$sqlline = trim( $line );

		// check if it's a comment
		if( ereg( "^--", $sqlline ) )
		{
			continue;
		}

		$pos = strrpos( $sqlline, ';' );
		if( $pos === false )
		{
			$sql .= $sqlline . ' ';
			continue;
		}
		
		$sql .= substr( $sqlline, 0, $pos );

		//print( "<br>\n" );
		//print( "executing...<br>\n" );

		if( !db()->execute( $sql ) )
		{
			print( "SQL ERROR: ".db()->lastError()."<br>\n" );
			return false;
		}

		$sql = '';
	}
	print( "<br>\n" );

	return true;
}

/*
 * initDatabase()
 * initialize database with sql files
 */
function initDatabase()
{
	$dbType = strtolower( Conf::$c['db']['type'] );
	$dbFiles = array( 'core/sql/'.$dbType.'.sql', 'site/sql/'.$dbType.'.sql' );

	foreach( $dbFiles as $file )
	{
		if( !file_exists($file) ) continue;

		print( 'initDatabase: parsing and executing file "'.$file.'" <br>'."\n" );

		if( !executeSQLFile($file) )
		{
			print( 'initDatabase: execution error <br'."\n" );
			continue;
		}
	}

	print( 'initDatabase: database initialized <br>'."\n" );
}

function initUserGroup()
{
	require_once( 'core/database_fct.php' );


	// creating admin, anonymous users and admin group
	$adminUserID = -1;
	$adminUser = Conf::$c['special']['username']['admin'];
	$adminGroupID = -1;
	$adminGroup = Conf::$c['special']['groupname']['admin'];
	$adminPassword = 'password';
	$anonUserID = -1;
	$anonUser = Conf::$c['special']['username']['anonymous'];
	$anonGroupID = -1;
	$anonGroup = Conf::$c['special']['groupname']['anonymous'];
	$anonPassword = '';

	$adminGroupID = CoreDBFct::getGroupId( $adminGroup );
	if( $adminGroupID < 0 )
	{
		$adminGroupID = CoreDBFct::insertGroup( $adminGroup );
		if( $adminGroupID < 0 ) 
		{
			setError( "create admin group" );
			error();
		}
	}

	$anonGroupID = CoreDBFct::getGroupId( $anonGroup );
	if( $anonGroupID < 0 )
	{
		$anonGroupID = CoreDBFct::insertGroup( $anonGroup );
		if( $anonGroupID < 0 ) 
		{
			setError( "create anon group" );
			error();
		}
	}

	$adminUserID = CoreDBFct::getUserId( $adminUser );
	if( $adminUserID < 0 )
	{
		$adminUserID = CoreDBFct::insertUser( $adminUser, $adminPassword, "admin@admin.com" );
		if( $adminUserID < 0 ) 
		{
			setError( "create admin user" );
			error();
		}
	}

	$anonUserID = CoreDBFct::getUserId( $anonUser );
	if( $anonUserID < 0 )
	{
		$anonUserID = CoreDBFct::insertUser( $anonUser, $anonPassword, "anonymous@anonymous.com" );
		if( $anonUserID < 0 )
		{
			setError( "createn anon user" );
			error();
		}
	}

	if( !CoreDBFct::isUserInGroup( $adminUserID, $adminGroupID ) )
	{
		if( !CoreDBFct::addUserToGroup( $adminUserID, $adminGroupID ) )
		{
			setError( "add admin user to admin group" );
			error();
		}
	}

	if( !CoreDBFct::isUserInGroup( $anonUserID, $anonGroupID ) )
	{
		if( !CoreDBFct::addUserToGroup( $anonUserID, $anonGroupID ) )
		{
			setError( "add anon user to anon group" );
			error();
		}
	}

	print( "initUserGroup: done...<br>\n" );
}

/*
 * find, load, and initialize every declared services and their defined methods
 */
function initServicesDatabase()
{
	require_once( 'core/database_fct.php' );

	$mainDirs = array( 'core', 'site' );

	// include all service
	foreach( $mainDirs as $dir )
	{
		$serviceFiles = Service::findServiceFiles( $dir );

		foreach( $serviceFiles as $file )
		{
			print( 'initServicesDatabase: including service: '.$file.' <br>'."\n" );
			include( $file );
		}
	}

	$services = Service::getRegisteredServices();
	$servicesMethodsIds = array();

	// update database for all services
	foreach( $services as $serviceName => $serviceDesc )
	{
		print( 'initServicesDatabase: updating database for service: '.$serviceName.' <br>'."\n" );
		$svc = new $serviceName();
		$ret = $svc->updateDatabase();
		if( is_bool($ret) && $ret == false ) continue;

		list( $serviceId, $methodIds ) = $ret;
		$servicesMethodsIds[ $serviceId ] = $methodIds;
	}

	// Allowing group admin to call every methods of every services
	$grpAdminId = CoreDBFct::getGroupId( Conf::$c['special']['groupname']['admin'] );
	if( $grpAdminId < 0 ) die( "initServicesDatabase: admin (".Conf::$c['special']['groupname']['admin'].") group not created" );

	print( 'initServicesDatabase: allowing group "'.Conf::$c['special']['groupname']['admin'].'" to do everything! <br>'."\n" );
	foreach( $servicesMethodsIds as $svcId => $mthIds )
	{
		foreach( $mthIds as $mthId )
		{
			if( !CoreDBFct::isCallAllowed( $grpAdminId, $svcId, $mthId ) )
				CoreDBFct::insertCallPermission( $grpAdminId, $svcId, $mthId );
		}
	}
}


?>
